package com.zhongpengcheng.fortune.es.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.zhongpengcheng.fortune.es.common.pojo.po.GalaxyPO;
import com.zhongpengcheng.fortune.es.pojo.es.GalaxyDO;
import com.zhongpengcheng.fortune.es.pojo.es.StarDO;
import com.zhongpengcheng.fortune.es.service.SeedSearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.InnerHitBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SourceFilter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;

/**
 * 种子检索接口
 *
 * @author zhongpengcheng
 * @date 2021-10-01 20:26:49
 **/
@RestController
@Slf4j
public class SeedSearchController {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private SeedSearchService searchService;

    @SentinelResource(value = "seedSearch", blockHandler = "blockHandler")
    @GetMapping("/seed/sentienl")
    public void sentinelTest() {
        log.info("access on " + DateUtil.now());
    }

    public void blockHandler(BlockException ex) throws BlockException {
        throw ex;
    }

    @GetMapping("/seed/_search")
    public Object searchSeeds(@RequestBody GalaxyPO galaxyPO) {

//        return searchService.searchSeed(galaxyQO);

        BoolQueryBuilder query = QueryBuilders
                .boolQuery()
                .filter(
                        QueryBuilders
                                .nestedQuery("stars", buildStarQuery(galaxyPO), ScoreMode.None)
                                .innerHit(buildInnerHits())
                );

        SourceFilter sourceFilter = new FetchSourceFilterBuilder()
                .withIncludes("birthPlanetId")
                .build();

        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(query)
                .withPageable(PageRequest.of(0, 10))
                .withSourceFilter(sourceFilter)
                .build();

        SearchHits<GalaxyDO> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, GalaxyDO.class);

        ArrayList<GalaxyDO> galaxyList = new ArrayList<>();

        searchHits.getSearchHits().forEach(galaxy -> {
            GalaxyDO galaxyDO = galaxy.getContent();
            SearchHits<?> stars = galaxy.getInnerHits("stars");
            if (stars == null) {
                return;
            }
            galaxyDO.setStars(new ArrayList<>());
            stars.getSearchHits().forEach(star -> galaxyDO.getStars().add((StarDO) star.getContent()));
            galaxyList.add(galaxyDO);
        });
        System.out.println(query);
        System.out.println(JSON.toJSONString(galaxyList));

//        searchRequest.source(searchSourceBuilder);
//
//        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
//
//        System.out.println(
//                JSON.toJSONString(response
//                        .getHits()
//                        .getHits()[0]
//                        .getInnerHits()
//                        .get("stars")
//                        .getHits()[0]
//                        .getSourceAsMap(), true));
        return "";
    }

    private InnerHitBuilder buildInnerHits() {
        return new InnerHitBuilder()
                .setIgnoreUnmapped(true)
                .setFrom(0)
                .setSize(100)
                .setVersion(false)
                .setExplain(false)
                .setTrackScores(false);
    }

    private QueryBuilder buildStarQuery(GalaxyPO param) {
        return QueryBuilders.boolQuery()
//                .filter(QueryBuilders.termQuery("stars.singularities.tidalLocked", Boolean.TRUE))
//                .filter(QueryBuilders.termQuery("stars.veins.crysrub", Boolean.TRUE))
//                .filter(QueryBuilders.termQuery("stars.veins.grat", Boolean.TRUE))
//                .filter(QueryBuilders.termQuery("stars.veins.bamboo", Boolean.TRUE))
                .filter(QueryBuilders.rangeQuery("stars.distance").lte(1000))
                .filter(QueryBuilders.rangeQuery("stars.dysonLumino").gte(10));
    }
}
